package org.jeecg.modules.demo.com.kunpeng.controller;

import java.io.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jeecg.modules.demo.com.kunpeng.entity.ProjectDetailsInsert;
import org.jeecg.modules.demo.com.kunpeng.entity.dto.ProjectListQueryDTO;
import org.jeecg.modules.demo.com.kunpeng.service.IProjectPurchaseService;
import org.jeecg.modules.demo.com.kunpeng.vo.*;
import org.jeecg.modules.demo.com.kunpeng.web.JsonResult;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.vo.LoginUser;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.com.kunpeng.entity.ProjectDetails;
import org.jeecg.modules.demo.com.kunpeng.entity.Project;
import org.jeecg.modules.demo.com.kunpeng.service.IProjectService;
import org.jeecg.modules.demo.com.kunpeng.service.IProjectDetailsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;


 /**
 * @Description: 项目表
 * @Author: jeecg-boot
 * @Date:   2022-12-03
 * @Version: V1.0
 */
@Api(tags="项目表")
@RestController
@RequestMapping("/com.kunpeng/project")
@Slf4j
public class ProjectController {
	 @Autowired
	 private IProjectService projectService;
	 @Autowired
	 private IProjectDetailsService projectDetailsService;
	 @Autowired
	 private IProjectPurchaseService projectPurchaseService;
	 /**
	  * 分页列表查询
	  *
	  * @param project
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "项目表-分页列表查询")
	 @ApiOperation(value = "项目表-分页列表查询", notes = "项目表-分页列表查询")
	 @GetMapping(value = "/list")
	 public Result<IPage<Project>> queryPageList(Project project,
												 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
												 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
												 HttpServletRequest req) {

		 QueryWrapper<Project> queryWrapper = QueryGenerator.initQueryWrapper(project, req.getParameterMap());
		 Page<Project> page = new Page<Project>(pageNo, pageSize);
		 IPage<Project> pageList = projectService.page(page, queryWrapper);
		 return Result.OK(pageList);
	 }

	 /**
	  * 添加
	  *
	  * @param projectPage
	  * @return
	  */
	 @AutoLog(value = "项目表-添加")
	 @ApiOperation(value = "项目表-添加", notes = "项目表-添加")
	 //@RequiresPermissions("com.kunpeng:project:add")
	 @PostMapping(value = "/add")
	 public Result<String> add(@RequestBody ProjectPage projectPage) {
		 System.out.println(projectPage.toString());
		 Project project = new Project();
		 //把项目表的数据复制到project对象
		 BeanUtils.copyProperties(projectPage, project);
		 //把数据传到业务层进行插入
		 projectService.saveMain(project, projectPage.getProjectDetailsInsertsList());
		 return Result.OK("添加成功！");
	 }

	 /**
	  * 编辑
	  *
	  * @param projectPage
	  * @return
	  */
	 @AutoLog(value = "项目表-编辑")
	 @ApiOperation(value = "项目表-编辑", notes = "项目表-编辑")
	 //@RequiresPermissions("com.kunpeng:project:edit")
	 @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
	 public Result<String> edit(@RequestBody ProjectPage projectPage) {
		 Project project = new Project();
		 BeanUtils.copyProperties(projectPage, project);
		 Project projectEntity = projectService.getById(project.getId());
		 if (projectEntity == null) {
			 return Result.error("未找到对应数据,请重新输入！");
		 }
		 System.out.println("开始执行修改操作！");
		 projectService.updateMain(project, projectPage.getProjectDetailsInsertsList());
		 return Result.OK("编辑成功!");
	 }

	 /**
	  * 通过id删除
	  *
	  * @param id
	  * @return
	  */
	 @AutoLog(value = "项目表-通过id删除")
	 @ApiOperation(value = "项目表-通过id删除", notes = "项目表-通过id删除")
	 //@RequiresPermissions("com.kunpeng:project:delete")
	 @DeleteMapping(value = "/delete")
	 public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
		 projectService.delMain(id);
		 return Result.OK("删除成功!");
	 }

	 /**
	  * 批量删除
	  *
	  * @param ids
	  * @return
	  */
	 @AutoLog(value = "项目表-批量删除")
	 @ApiOperation(value = "项目表-批量删除", notes = "项目表-批量删除")
	 //@RequiresPermissions("com.kunpeng:project:deleteBatch")
	 @DeleteMapping(value = "/deleteBatch")
	 public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
		 this.projectService.delBatchMain(Arrays.asList(ids.split(",")));
		 return Result.OK("批量删除成功！");
	 }

	 /**
	  * 通过id查询
	  *
	  * @param id
	  * @return
	  */
	 //@AutoLog(value = "项目表-通过id查询")
	 @ApiOperation(value = "项目表-通过id查询", notes = "项目表-通过id查询")
	 @GetMapping(value = "/queryById")
	 public Result<Project> queryById(@RequestParam(name = "id", required = true) String id) {
		 Project project = projectService.getById(id);
		 if (project == null) {
			 return Result.error("未找到对应数据");
		 }
		 return Result.OK(project);
	 }

	 /**
	  * 通过id查询项目详情表
	  *
	  * @param projectID
	  * @return
	  */
	 //@AutoLog(value = "项目详细信息表通过主表ID查询")
	 @ApiOperation(value = "项目详细信息表主表ID查询", notes = "项目详细信息表-通主表ID查询")
	 @GetMapping(value = "/queryProjectDetailsByMainId")
	 public Result<List<ProjectDetails>> queryProjectDetailsListByMainId(@RequestParam(name = "id", required = true) String projectID) {
		 List<ProjectDetails> projectDetailsList = projectDetailsService.selectByMainId(projectID);
		 return Result.OK(projectDetailsList);
	 }

	 /**
	  * 导出excel
	  *
	  * @param request
	  * @param project
	  */
	 //@RequiresPermissions("com.kunpeng:project:exportXls")
	 @RequestMapping(value = "/exportXls")
	 public ModelAndView exportXls(HttpServletRequest request, Project project) {
		 // Step.1 组装查询条件查询数据
		 QueryWrapper<Project> queryWrapper = QueryGenerator.initQueryWrapper(project, request.getParameterMap());
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 //配置选中数据查询条件
		 String selections = request.getParameter("selections");
		 if (oConvertUtils.isNotEmpty(selections)) {
			 List<String> selectionList = Arrays.asList(selections.split(","));
			 queryWrapper.in("id", selectionList);
		 }
		 //Step.2 获取导出数据
		 List<Project> projectList = projectService.list(queryWrapper);
		 // Step.3 组装pageList
		 List<ProjectPage> pageList = new ArrayList<ProjectPage>();
		 for (Project main : projectList) {
			 ProjectPage vo = new ProjectPage();
			 BeanUtils.copyProperties(main, vo);
			 List<ProjectDetails> projectDetailsList = projectDetailsService.selectByMainId(main.getId());
			 //类型转换
			 List<ProjectDetailsInsert> projectDetailsInsertList = new ArrayList<>();
			 for (ProjectDetails s : projectDetailsList) {
				 ProjectDetailsInsert projectDetailsInsert = new ProjectDetailsInsert();
				 BeanUtils.copyProperties(s, projectDetailsInsert);
				 projectDetailsInsertList.add(projectDetailsInsert);
			 }
			 vo.setProjectDetailsInsertsList(projectDetailsInsertList);
			 pageList.add(vo);
		 }
		 // Step.4 AutoPoi 导出Excel
		 ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
		 mv.addObject(NormalExcelConstants.FILE_NAME, "项目表列表");
		 mv.addObject(NormalExcelConstants.CLASS, ProjectPage.class);
		 mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("项目表数据", "导出人:" + sysUser.getRealname(), "项目表"));
		 mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
		 return mv;
	 }

	 /**
	  * 通过excel导入数据
	  *
	  * @param request
	  * @param response
	  * @return
	  */
	 //@RequiresPermissions("com.kunpeng:project:importExcel")
	 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
	 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
		 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		 Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
		 for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
			 // 获取上传文件对象
			 MultipartFile file = entity.getValue();
			 ImportParams params = new ImportParams();
			 params.setTitleRows(2);
			 params.setHeadRows(1);
			 params.setNeedSave(true);
			 try {
				 List<ProjectPage> list = ExcelImportUtil.importExcel(file.getInputStream(), ProjectPage.class, params);
				 for (ProjectPage page : list) {
					 Project po = new Project();
					 BeanUtils.copyProperties(page, po);
					 projectService.saveMain(po, page.getProjectDetailsInsertsList());
				 }
				 return Result.OK("文件导入成功！数据行数:" + list.size());
			 } catch (Exception e) {
				 log.error(e.getMessage(), e);
				 return Result.error("文件导入失败:" + e.getMessage());
			 } finally {
				 try {
					 file.getInputStream().close();
				 } catch (IOException e) {
					 e.printStackTrace();
				 }
			 }
		 }
		 return Result.OK("文件导入失败！");
	 }

	 /**
	  * 根据关键字查询项目列表
	  *
	  * @param projectListQueryDTO
	  * @param pageNo
	  * @param pageSize
	  * @return
	  */
	 @ApiOperation(value = "项目表-根据关键字分页列表查询", notes = "项目表-根据关键字分页列表查询")
	 @PostMapping(value = "/listByKeyWords")
	 public Result<IPage<ProjectListQueryVO>> listByKeyWords(@RequestBody ProjectListQueryDTO projectListQueryDTO,
															@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
															@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
		 log.info("开始处理根据关键字查询项目列表请求...");
		 Result<Page<ProjectListQueryVO>> result = new Result<Page<ProjectListQueryVO>>();
		 Page<ProjectListQueryVO> pageList = new Page<ProjectListQueryVO>(pageNo, pageSize);
		 pageList = projectService.listByKeyWords(pageList, projectListQueryDTO);//通知公告消息
		 if (pageList.getRecords().size() == 0) {
			 return Result.error("没有符合条件的数据，请重新输入！");
		 }
		 log.info("查询当前页：" + pageList.getCurrent());
		 log.info("查询当前页数量：" + pageList.getSize());
		 log.info("查询结果数量：" + pageList.getRecords().size());
		 log.info("数据总数：" + pageList.getTotal());
		 result.setSuccess(true);
		 result.setResult(pageList);
		 return Result.ok(pageList);
	 }

	 /**
	  * 处理文件上传
	  *
	  * @param pic
	  * @return
	  */
	 @ApiOperation(value = "文件上传接口")
	 @PostMapping(value = "/upload")
	 public Result<FileVO> upload(@RequestPart("file") MultipartFile pic) {
		 String fileDir = "E:/projectFiles";
		 String fileName = pic.getOriginalFilename();
		 //获取文件后缀名
		 String suffix = fileName.substring(fileName.lastIndexOf("."));
		 fileName = UUID.randomUUID() + suffix;
		 //文件夹不存在则创建
		 File dirFile = new File(fileDir);
		 if (!dirFile.exists()) {
			 dirFile.mkdirs();
		 }
		 //文件写入磁盘
		 String filePath = fileDir + "/" + fileName;
		 try {
			 pic.transferTo(new File(filePath));
		 } catch (IOException e) {
			 e.getMessage();
		 }
		 //返回文件对象
		 FileVO file = new FileVO();
		 file.setFileName(fileName);
		 file.setFileUrl(fileDir);
		 return Result.ok(file);
	 }

	 /**
	  * 文件下载接口
	  *
	  * @param
	  * @param response
	  * @return
	  */
	 @ApiOperation(value = "文件下载接口")
	 @GetMapping(value = "/download")
	 public Result<HttpServletResponse> download(@RequestParam String path, HttpServletResponse response) throws IOException {
			 try {
				 // path是指预下载的文件的路径。
				 File file = new File(path);
				 // 取得文件名。
				 String filename = file.getName();
				 // 取得文件的后缀名。
				 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
				 // 以流的形式下载文件。
				 InputStream fis = new BufferedInputStream(new FileInputStream(path));
				 byte[] buffer = new byte[fis.available()];
				 fis.read(buffer);
				 fis.close();
				 // 清空response
				 response.reset();
				 // 设置response的Header
				 response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
				 response.addHeader("Content-Length", "" + file.length());
				 OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
				 response.setContentType("application/octet-stream");
				 response.reset();
				 toClient.write(buffer);
				 toClient.flush();
				 toClient.close();
			 } catch (IOException ex) {
				 ex.printStackTrace();
			 }
			 return Result.ok(response);
		 }

	 /**
	  * 根据项目id查询项目详情
	  * @param projectId
	  * @return
	  */
	 @ApiOperation("根据项目id查询项目详情")
	 @GetMapping(value = "/selectByProjectId")
	 public JsonResult<ProjectStandardVO> selectByProjectId(String projectId){
	 	log.info("开始处理根据项目id查询项目详情请求！");
		 ProjectStandardVO projectStandardVO = projectService.selectByProjectId(projectId);
		 return JsonResult.ok(projectStandardVO);
	 }

	 /**
	  * 获取客户列表
	  * @return
	  */
	 @ApiOperation("获取客户列表")
	 @GetMapping(value = "/listCustomer")
	 public Result<List<CustomerInNameListVO>> listCustomer(){
	 	 log.info("开始处理获取客户列表请求...");
		 List<CustomerInNameListVO> customerInNameListVOS = projectService.customerList();
		 log.info("即将返回客户列表给前端");
		 return Result.OK(customerInNameListVOS);
	 }

	 /**
	  * 获取项目起始时间
	  * @param projectId
	  * @return
	  */
	 @ApiOperation("获取项目起始时间")
	 @PostMapping(value = "/selectProjectDateReturn")
	 public Result<ProjectPhaseDetailsVO> selectProjectDateReturn(String projectId){
		 List<ProjectDateReturn> projectDateReturnList = projectService.selectProjectDetailsDate(projectId);
		 List<DateRange> dateRanges = projectService.projectStartEndTime(projectId);
		 ProjectPhaseDetailsVO projectPhaseDetailsVO=new ProjectPhaseDetailsVO();
		 projectPhaseDetailsVO.setProjectDateReturnList(projectDateReturnList);
		 projectPhaseDetailsVO.setRangeList(dateRanges);
		 for(ProjectDateReturn projectDateReturn:projectDateReturnList){
			 List<Integer> projectPhaseList=new ArrayList<>();
			 Integer phaseId=1;
			 LocalDate phaseStartTime = projectDateReturn.getStartTime();
			 Long phaseStartTimeMilli = phaseStartTime.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
			 LocalDate phaseEndTime = projectDateReturn.getEndTime();
			 Long phaseEndTimeMilli = phaseEndTime.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
			 for(DateRange dateRange:dateRanges){
			 	//计算项目阶段时间和按周分的项目时间是否存在交集
				 LocalDate RangeStartDate = dateRange.getStartDate();
				 Long rangeStartTimeMilli = RangeStartDate.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
				 LocalDate RangeEndDate = dateRange.getEndDate();
				 Long rangeEndTimeMilli = RangeEndDate.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
				 if((phaseStartTimeMilli >= rangeStartTimeMilli && phaseStartTimeMilli < rangeEndTimeMilli)
						||
					((phaseStartTimeMilli > rangeStartTimeMilli) && phaseStartTimeMilli <= rangeEndTimeMilli)
						||
					((rangeStartTimeMilli >= phaseStartTimeMilli) && rangeStartTimeMilli < phaseEndTimeMilli)
						||
					((rangeStartTimeMilli > phaseStartTimeMilli) && rangeStartTimeMilli <= phaseEndTimeMilli)){
					 projectPhaseList.add(phaseId++);
					 continue;
				 }
				 phaseId++;
			 }
			 projectDateReturn.setProjectPhaseList(projectPhaseList);
		 }
		 /*System.out.println("获取到的项目各阶段起止时间:"+projectDateReturnList.toString());
		 System.out.println("按周划分项目起止时间："+dateRanges.toString());*/
		 return Result.ok(projectPhaseDetailsVO);
	 }

	 /**
	  * 根据id修改项目回款状态
	  */
	 @ApiOperation("根据id修改项目回款状态")
	 @PostMapping(value = "/updateReturnMoneyStatus")
	 public Result<String> updateReturnMoneyStatus(String projectId,String returnMoneyStatus){
		 System.out.println("根据id修改项目回款状态：id="+projectId+",returnMoneyStatus:"+returnMoneyStatus);
	 	projectService.updateReturnMoneyStatus(projectId,returnMoneyStatus);
	 	return Result.ok("修改成功！");
	 }

	 /**
	  * 项目编号生产器
	  */
	 /*@ApiOperation("项目编号或采购单号生成器")
	 @GetMapping(value = "/createProjectIdOrPurchaseId")
	 public Result<String> createProjectOrPurchaseId(String prefix){
	 	LocalDate now = LocalDate.now();
	 	DateTimeFormatter dtf= DateTimeFormatter.ofPattern("yyyy-MM-dd"); //定义时间格式
		String dateStr = now.format(dtf); //转换成String类型
		String[] split = dateStr.split("-");
		if(prefix.equals("XM")) {
			String projectId = "XM" + split[0]+split[1] + split[2];
			System.out.println("项目前缀："+projectId);
			Integer projectIdSuffix = projectService.listProjectIdByPrefix(projectId);
			if(projectIdSuffix<=9){
				projectId+="00"+projectIdSuffix;
			}else if(projectIdSuffix>9 && projectIdSuffix<=99){
				projectId+="0"+projectIdSuffix;
			}else if(projectIdSuffix>99){
				projectId+=projectIdSuffix;
			}
			return Result.OK(projectId);
		}else if(prefix.equals("CGSQ")){
			String purchaseId = "CGSQ" + split[0]+split[1] + split[2];
			Integer purchaseIdSuffix = projectPurchaseService.listPurchaseIdByPurchaseId(purchaseId);
			if(purchaseIdSuffix<=9){
				purchaseId+="00"+purchaseIdSuffix;
			}else if(purchaseIdSuffix>9 && purchaseIdSuffix<=99){
				purchaseId+="0"+purchaseIdSuffix;
			}else if(purchaseIdSuffix>99){
				purchaseId+=purchaseIdSuffix;
			}
			return Result.OK(purchaseId);
		}
		return Result.error("项目编号或采购单号生成失败!");
	 }*/

	 /**
	  * 根据客户名称获取项目名称和编号
	  *
	  */
	 @ApiOperation("根据客户名称获取项目名称和项目编号")
	 @GetMapping(value = "/listProjectNameOrIdByCustomerName")
	 public Result<List<ProjectVO>> queryProjectNameOrId(String customerName){
		 List<ProjectVO> projectVOList = projectService.listProjectByCustomerName(customerName);
		 return Result.ok(projectVOList);
	 }

	 /**
	  * 根据项目名称获取项目阶段列表
	  */
	 @ApiOperation("根据项目名称获取项目阶段列表")
	 @GetMapping(value = "/listProjectPhaseByProjectName")
	 public Result<List<String>> listProjectPhaseByProjectName(String projectName){
		 List<String> projectPhaseList = projectService.listProjectPhaseByMainId(projectName);
		 return Result.ok(projectPhaseList);
	 }

	 /**
	  * 根据id修改项目的已回款金额值
	  */
	 @ApiOperation("根据id修改项目的已回款金额值")
	 @GetMapping(value = "/updateAlreadyReturnMoney")
	 public Result<String> updateAlreadyReturnMoney(String id, BigDecimal alreadyReturnMoney){
		 System.out.println("开始处理根据id修改项目回家金额");
	 	projectService.updateAlreadyReturnMoney(id,alreadyReturnMoney);
	 	return Result.ok("修改成功");
	 }

	 /**
	  * 文件打印
	  * @param
	  * @return
	  */
	/* @ApiOperation("文件打印接口")
	 @PostMapping(value = "/print")
	public Result<String> print(String fileName,String printerName){
		FilePrintUtils.PDFPrint(new File(fileName), printerName, 412, 582, 0, 0);
		return Result.ok();
	}*/
 }

